import { getTaskType } from '@src/api/TaskApi'
import { getTaskFlowNode } from '@src/api/SettingTaskApi'
/* entity */
import TaskType from '@model/entity/TaskType'
import TaskApprove from '@model/entity/TaskApprove'
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
import TaskActionEnum from '@model/enum/TaskActionEnum'
import TaskStateProcessEnum from '@model/enum/TaskStateProcessEnum'
/* model */
import { getTaskTypeResult } from '@model/param/out/Task'
/* types */
import FlowSetting from '@model/types/FlowSetting'
/* vue */
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
import { CreateElement } from 'vue'
/* service */
import { checkApprove } from '@service/TaskService'
/* scss */
import '@src/modules/task/components/TaskProcessSteps/TaskProcessSteps.scss'
import { taskSteps } from '@src/modules/guideForNewUser/initData.js'
import i18n from '@src/locales'
import { TranslateResult } from 'vue-i18n'

interface TaskProcessStep {
  // 节点名称
  name: string,
  // 节点值
  value: string,
  // 图标
  icon: string,
  // 工单状态
  state: string | string[],
  // 当前节点流程信息
  flow?: any
}

/* 步骤条对象 */
const StepMap: { [x: string]: TaskProcessStep } = {
  // 新建
  [TaskActionEnum.CREATE.value]: { name: TaskActionEnum.CREATE.name as string, value: TaskActionEnum.CREATE.value, icon: 'xinjian', state: TaskStateProcessEnum.CREATED.value },
  // 指派
  [TaskActionEnum.ALLOT.value]: { name: TaskActionEnum.ALLOT.name as string, value: TaskActionEnum.ALLOT.value, icon: 'zhipai', state: TaskStateProcessEnum.ALLOCATED.value },
  // 接受
  [TaskActionEnum.ACCEPT.value]: { name: TaskActionEnum.ACCEPT.name as string, value: TaskActionEnum.ACCEPT.value, icon: 'jieshou', state: TaskStateProcessEnum.ACCEPTED.value },
  // 开始
  [TaskActionEnum.START.value]: { name: TaskActionEnum.START.name as string, value: TaskActionEnum.START.value, icon: 'kaishi', state: TaskStateProcessEnum.PROCESSING.value },
  // 完成
  [TaskActionEnum.FINISH.value]: { name: TaskActionEnum.FINISH.name as string, value: TaskActionEnum.FINISH.value, icon: 'wancheng', state: TaskStateProcessEnum.FINISHED.value }
}

@Component({
  name: ComponentNameEnum.TaskProcessSteps
})
export default class TaskProcessSteps extends Vue {
  /* 工单节点状态 */
  @Prop() state: string | undefined
  /* 工单类型id */
  @Prop() templateId: string | undefined

  /* 是否是引导展示 */
  @Prop() readonly justGuide: any | undefined

  /* 工单节点灰度 */
  @Prop() taskFlowExtend: boolean | undefined

  /* 当前节点id */
  @Prop() currentNodeId: string | undefined

  /* 步骤条列表 */
  private steps: TaskProcessStep[] = []
  /* 工单类型数据 */
  private taskType: TaskType | null = null
  /* 上一个自定义节点的id */
  private currentCustomNodeId: String | null = null

  @Watch('templateId')
  onTemplateIdChanged() {
    this.fetchTaskType()
  }

  /** 
   * @description 获取当前状态的索引 当前的步骤流程
  */
  private get active(): number {
    let index = 0
    let step: TaskProcessStep | null = null

    for (let i = 0; i < this.steps.length; i++) {
      step = this.steps[i]
      if (this.isCurrentState(step.state)) {
        index = i + 1
        break
      }
    }

    return index
  }

  /** 
   * @description 查询工单类型配置
  */
  public async fetchTaskType() {
    if (!this.templateId) {
      return console.warn('Caused: [TaskProcessSteps] templateId is empty')
    }
    // 开启了灰度查询自定义节点
    let taskCustomNode: any = []
    if(this.taskFlowExtend) {
      const { result, success } = await getTaskFlowNode({taskTypeId: this.templateId});
      let previousNode = {}
      result?.forEach((item: any, index: Number) => {
        if(item.id === this.currentNodeId) {
          previousNode = result[index - 1]
        }
      })

      if(previousNode?.type === 'normal') {
        this.currentCustomNodeId = previousNode.id;
      }
      if(success) taskCustomNode = result;
    }

    let params = { id: this.templateId || '' }
    return (
      getTaskType(params)
        .then((result: getTaskTypeResult) => {
          let isSuccess = result.succ
          if (!isSuccess) return
          
          this.taskType = result.data || null

          const needApproveForCreate = checkApprove(this.taskType, 'create', { id: '' }, {})?.needApprove ?? false
          this.$emit('updateCreateApprove', needApproveForCreate)

          this.setSteps(taskCustomNode)
          
        })
        .catch(err => {
          console.error(err)
        })
    )
  }

  private getScopedSlots(step: TaskProcessStep) {
    let { flow, value, icon } = step
    // 判空
    if (!flow) {
      return console.warn('Caused: [TaskProcessSteps] getScopedSlots flow is empty')
    }

    // 审批信息
    let taskApprove: TaskApprove | null = this.taskType ? checkApprove(this.taskType, value, { id: '' }, {}) : null
    // 处理自定义节点的审批和超时信息
    if(flow.type === 'normal') {
      taskApprove = {
        needApprove: flow?.approveSetting?.vipApprove == 1
      }
    }
    // 超时时间
    let overTime: string | null = flow?.overTime ? flow.overTime : null
    let newOverTimeSetting: any;
    let currOverTimeSetting: any;
    let overTimeStatus: any;
    try {
      // 处理自定义节点超时信息
      if(flow.type === 'normal') {
        overTimeStatus = flow.overTimeStatus && overTime;
      }else {
        newOverTimeSetting = this.taskType?.config?.newOverTimeSetting;
        currOverTimeSetting = newOverTimeSetting.find((item: any) => item.overTimeState === value) || {};
        overTimeStatus = currOverTimeSetting.overTimeStatus && overTime;
      }
    } catch (error) {
      console.warn(error, 'error try catch');
    }



    const scopedSlots = {
      icon: (props: any) => {
        return <i class={['iconfont', `icon-${icon}`]}></i>
      },
      description: (props: any) => {
        return (
          <div class='task-step-flow'>
            {
              taskApprove
              && taskApprove.needApprove
              && <div class='task-step-flow-approve'>{i18n.t('task.components.taskProcessSteps.needApprove')}</div>
            }
            {
              overTimeStatus
              && <div class='task-step-flow-overtime'>{i18n.t('task.components.taskProcessSteps.overTimeHour', {num: overTime})}</div>
            }
          </div>
        )
      }
    }

    return scopedSlots
  }

  /* 判断是否是当前状态 */
  private isCurrentState(state: string | string[]): boolean {
    const currentState = this.currentCustomNodeId ?? this.state
    return state == currentState || (Array.isArray(state) && state.indexOf(currentState || '') > -1)
  }

  /** 
   * @description 设置步骤条数据
  */
  public setSteps(taskCustomNode = []) {
    if (!this.taskType) {
      return console.warn('Caused: [TaskProcessSteps] taskType is empty')
    }

    this.steps = []

    if(taskCustomNode?.length) {
      taskCustomNode?.forEach((item: any) => {
        if(item.type === 'normal') {
          this.steps.push({
            name: item?.data?.nodeBtnName ?? '',
            // 节点值
            value: item.id,
            // 图标
            icon: 'liuchengjiedian',
            // 工单状态
            state: item.id,
            // 当前节点流程信息
            flow: {...item, ...item.data}
          })
        }else {
          const currentFlow = this.taskType?.flowSetting?.[item.type] ?? ({...item, ...item.data}) ?? {}
          // 是否开启该流程
          let isEnabled = currentFlow?.state === true
          // 开启则 添加该流程
          isEnabled
          && StepMap[item.type]
          && this.steps.push({ ...StepMap[item.type], flow: currentFlow })
        }
      })
    }else {
      // 工单流程设置
      let flowSetting: any = this.taskType.flowSetting
      let currentFlow: FlowSetting = new FlowSetting()
      // 遍历添加步骤信息
      for (let flow in flowSetting) {
        currentFlow = flowSetting[flow]
        // 是否开启该流程
        let isEnabled = currentFlow?.state === true
        // 开启则 添加该流程
        isEnabled
        && StepMap[flow]
        && this.steps.push({ ...StepMap[flow], flow: currentFlow })
      }
    }
  }

  mounted() {
    if (this.justGuide) this.steps = taskSteps;
    this.fetchTaskType()
  }

  render(h: CreateElement) {
    return (
      <div class={ComponentNameEnum.TaskProcessSteps}>
        <el-steps active={this.active} finish-status='success'>
          {
            this.steps.map((step: TaskProcessStep) => {
              return (
                <el-step title={step.name} scopedSlots={this.getScopedSlots(step)}></el-step>
              )
            })
          }
        </el-steps>
      </div>
    )
  }

}

